#include "kshape.h"
#include <QGraphicsSceneHoverEvent>
#include <QCursor>
#include <QGraphicsScene>
#include <QPainter>
#include <QDebug>

KShape::KShape(QGraphicsItem* parent)
	:QGraphicsItem(parent)
{
    setAcceptHoverEvents(true);

}

KShape::~KShape()
{
	
}

void KShape::moveShapeTo(const QPointF& target)
{
    QRectF localRect = boundingRect();
    //将图形整体移动，使局部坐标系的左上角对齐target
    setPos(target - localRect.topLeft());
}

void KShape::setStartPoint(const QPointF& pt)
{
    prepareGeometryChange();
    m_startPoint = pt;
}

void KShape::setEndPoint(const QPointF& pt)
{
    prepareGeometryChange();
    m_endPoint = pt;
    updateShape();
    update();
}

QPointF KShape::getStartPoint() const
{
    return m_startPoint;
}

QPointF KShape::getEndPoint() const
{
    return m_endPoint;
}

QRectF KShape::getRect() const
{
    return m_rect;
}

void KShape::setRect(const QRectF& rect)
{
    m_rect = rect;
}

KResizeRegion KShape::getRegion() const
{
    return m_region;
}

void KShape::setItemFlags()
{
	this->setFlags(
        QGraphicsItem::ItemIsSelectable |
        QGraphicsItem::ItemIsMovable |
        QGraphicsItem::ItemSendsGeometryChanges |
        QGraphicsItem::ItemIsFocusable
    );
}

void KShape::resizeFromCorner(KResizeRegion region, const QPointF& delta)
{
    prepareGeometryChange(); //准备修改前通知

    QRectF newRect = adjustRectForResize(m_rect, region, delta);

    if (!isResizedRectInBounds(newRect)) {
        //拒绝越界尺寸，直接return不更新
        return;
    }

    setRect(newRect);
    updateTransformInfo();
    update();


}

QGraphicsItem* KShape::toGraphicsItem()
{
    return this;
}

void KShape::finalizeItemGeometry()
{
    m_rect = QRectF(m_startPoint, m_endPoint).normalized();
    setPos(m_rect.topLeft()); //设置图元在 scene 坐标中的位置
    m_rect.moveTopLeft(QPointF(0, 0)); //设置图元在 item 局部坐标中的绘图起点
    updateTransformInfo();
}

//图形缩放大小，之后再调
void KShape::scaleBy(qreal factor)
{
    QPointF center = m_rect.center();
    QSizeF newSize = m_rect.size() * factor;
    QRectF scaled(center - QPointF(newSize.width() / 2, newSize.height() / 2), newSize);
    QRectF predictedSceneRect = mapToScene(scaled).boundingRect();

    //超出画布就不允许缩放
    QRectF sceneBounds = scene()->sceneRect();
    if (!sceneBounds.contains(predictedSceneRect)) {
        return;
    }

    setRect(scaled);

    //保留 start/end 的方向（避免翻转）
    bool leftToRight = (m_startPoint.x() <= m_endPoint.x());
    bool topToBottom = (m_startPoint.y() <= m_endPoint.y());

    QPointF newStart, newEnd;

    if (leftToRight && topToBottom) {
        newStart = scaled.topLeft();
        newEnd = scaled.bottomRight();
    }
    else if (!leftToRight && topToBottom) {
        newStart = scaled.topRight();
        newEnd = scaled.bottomLeft();
    }
    else if (leftToRight && !topToBottom) {
        newStart = scaled.bottomLeft();
        newEnd = scaled.topRight();
    }
    else {
        newStart = scaled.bottomRight();
        newEnd = scaled.topLeft();
    }

    setStartPoint(newStart);
    setEndPoint(newEnd);
}

void KShape::beginRotate(const QPointF& scenePos)
{
    setFlag(QGraphicsItem::ItemIsMovable, false);
    m_isRotating = true;
    m_rotationStartScenePos = scenePos;
    m_initialRotation = rotation();

}

void KShape::endRotate(const QPointF& scenePos)
{
    m_isRotating = false;
    setFlag(QGraphicsItem::ItemIsMovable, true);
}

void KShape::updateRotate(const QPointF& scenePos)
{
    if (!m_isRotating)
        return;

    QPointF center = mapToScene(m_rect.center()); // 旋转中心
    QLineF line1(center, m_rotationStartScenePos);
    QLineF line2(center, scenePos);
    qreal angle = line1.angleTo(line2);
    qreal newRotation = m_initialRotation - angle;

    // 生成旋转变换矩阵
    QTransform transform;
    transform.translate(center.x(), center.y());
    transform.rotate(newRotation);
    transform.translate(-center.x(), -center.y());

    // 将每个点映射到 scene 中，再做 boundingRect
    QPolygonF rotatedPolygon;
    for (const QPointF& pt : m_rectPoints) {
        rotatedPolygon << transform.map(mapToScene(pt));
    }
    QRectF rotatedBounds = rotatedPolygon.boundingRect();

    // 判断是否出界
    if (scene()->sceneRect().contains(rotatedBounds)) {
        setRotation(newRotation);
    }
}

QRectF KShape::getVisualBound() const
{
    if (qFuzzyIsNull(rotation())) {
        // 没旋转，直接返回图元本地矩形在 scene 中的范围
        return mapToScene(m_rect).boundingRect();
    }

    // 已旋转，使用四角变换后的外接矩形
    QPolygonF rotatedPolygon;
    for (const QPointF& pt : m_rectPoints) {
        rotatedPolygon << mapToScene(pt);
    }
    return rotatedPolygon.boundingRect();
}

void KShape::setLineWidth(double w)
{
    m_lineWidth = w;
    update();
}

void KShape::setLineColor(const QColor& c)
{
    m_lineColor = c;
    update();
}

void KShape::setLineStyle(Qt::PenStyle s)
{
    m_lineStyle = s;
    update();
}

void KShape::setFillColor(const QColor& c)
{
    m_fillColor = c;
    update();
}

void KShape::updateShape()
{
    prepareGeometryChange();
    m_rect = QRectF(m_startPoint, m_endPoint).normalized();
}

void KShape::hoverMoveEvent(QGraphicsSceneHoverEvent* event)
{
    KResizeRegion region = hitTest(event->pos());

    switch (region) {
    case KResizeRegion::TopLeft:
        m_region = KResizeRegion::TopLeft;
        setCursor(Qt::SizeFDiagCursor);
        break;

    case KResizeRegion::BottomRight:
        m_region = KResizeRegion::BottomRight;
        setCursor(Qt::SizeFDiagCursor);
        break;

    case KResizeRegion::TopRight:
        m_region = KResizeRegion::TopRight;
        setCursor(Qt::SizeBDiagCursor);
        break;

    case KResizeRegion::BottomLeft:
        m_region = KResizeRegion::BottomLeft;
        setCursor(Qt::SizeBDiagCursor);
        break;

    case KResizeRegion::Top:
        m_region = KResizeRegion::Top;
        setCursor(Qt::SizeVerCursor);
        break;

    case KResizeRegion::Bottom:
        m_region = KResizeRegion::Bottom;
        setCursor(Qt::SizeVerCursor);
        break;

    case KResizeRegion::Left:
        m_region = KResizeRegion::Left;
        setCursor(Qt::SizeHorCursor);
        break;

    case KResizeRegion::Right:
        m_region = KResizeRegion::Right;
        setCursor(Qt::SizeHorCursor);
        break;

    case KResizeRegion::RotateHandle:
        m_region = KResizeRegion::RotateHandle;
        setCursor(Qt::OpenHandCursor); //显示旋转提示
        break;

    default:
        m_region = KResizeRegion::None;
        unsetCursor();
        break;
    }
}

void KShape::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
    unsetCursor();
}

QVariant KShape::itemChange(GraphicsItemChange change, const QVariant& value)
{
    if (change == ItemPositionChange && scene()) {
        QPointF newPos = value.toPointF();
        QRectF bounds = scene()->sceneRect();

        //在图形准备被移动到 newPos 后，判断它“旋转状态下的实际边界”是不是还在 scene 边界里。
        QPolygonF rotatedPolygon;
        QTransform transform;
        //设定旋转中心
        transform.translate(newPos.x() + m_rect.center().x(),newPos.y() + m_rect.center().y());
        transform.rotate(rotation());
        //撤回移动
        transform.translate(-m_rect.center().x(), -m_rect.center().y());
        for (const QPointF& pt : m_rectPoints) {
            rotatedPolygon << transform.map(pt); //把每个点通过旋转矩阵 map 变换后加入新的 QPolygonF 中
        }
        QRectF rotatedBounds = rotatedPolygon.boundingRect();//最小包围矩形
        //若超出，限制在 bounds 内
        if (!bounds.contains(rotatedBounds)) {
            QPointF adjusted = newPos;

            if (rotatedBounds.left() < bounds.left())
                adjusted.setX(adjusted.x() + (bounds.left() - rotatedBounds.left()));
            if (rotatedBounds.right() > bounds.right())
                adjusted.setX(adjusted.x() - (rotatedBounds.right() - bounds.right()));
            if (rotatedBounds.top() < bounds.top())
                adjusted.setY(adjusted.y() + (bounds.top() - rotatedBounds.top()));
            if (rotatedBounds.bottom() > bounds.bottom())
                adjusted.setY(adjusted.y() - (rotatedBounds.bottom() - bounds.bottom()));

            return adjusted;
        }

        return newPos;
    }

    return QGraphicsItem::itemChange(change, value);
}


QRectF KShape::boundingRect() const
{
    return m_rect.adjusted(-1, -25, 1, 1); // 防止裁剪
}

void KShape::drawBoundingPreview(QPainter* painter) const
{
	QPen pen(Qt::blue, 2, Qt::DashLine);
	painter->setPen(pen);
	painter->setBrush(Qt::NoBrush);

	painter->drawRect(m_rect);

    // 画旋转手柄（小圆）
    QPointF topCenter = m_rect.topLeft() + QPointF(m_rect.width() / 2, 0);
    QPointF circleCenter = topCenter + QPointF(0, -15); // 上移 20px

    constexpr qreal radius = 6.0;
    QRectF circleRect(circleCenter.x() - radius, circleCenter.y() - radius, radius * 2, radius * 2);

    painter->setBrush(Qt::NoBrush); 
    painter->setPen(QPen(Qt::blue, 2)); 
    painter->drawEllipse(circleRect);
}

KResizeRegion KShape::hitTest(const QPointF& pos) const
{
    QRectF rect = m_rect;
    const qreal x = pos.x();
    const qreal y = pos.y();
    const qreal left = rect.left();
    const qreal right = rect.right();
    const qreal top = rect.top();
    const qreal bottom = rect.bottom();
    const qreal margin = MARGIN;

    //检查是否命中旋转手柄区域
    QPointF topCenter = rect.topLeft() + QPointF(rect.width() / 2, 0);
    QPointF rotateCenter = topCenter + QPointF(0, -20); // 上方偏移
    constexpr qreal radius = 6.0;
    QRectF rotateRect(rotateCenter.x() - radius, rotateCenter.y() - radius, radius * 2, radius * 2);
    if (rotateRect.contains(pos)) {
        return KResizeRegion::RotateHandle;
    }

    bool inLeft = std::abs(x - left) <= margin;
    bool inRight = std::abs(x - right) <= margin;
    bool inTop = std::abs(y - top) <= margin;
    bool inBottom = std::abs(y - bottom) <= margin;

    // 顺序判断，先判断角，再判断边
    if (inLeft && inTop) return KResizeRegion::TopLeft;
    if (inRight && inTop) return KResizeRegion::TopRight;
    if (inLeft && inBottom) return KResizeRegion::BottomLeft;
    if (inRight && inBottom) return KResizeRegion::BottomRight;
    if (inTop) return KResizeRegion::Top;
    if (inBottom) return KResizeRegion::Bottom;
    if (inLeft) return KResizeRegion::Left;
    if (inRight) return KResizeRegion::Right;

    return KResizeRegion::None;
}


void KShape::updateTransformInfo()
{
    setTransformOriginPoint(m_rect.center());  // 设置旋转中心为外接矩形中心

    m_rectPoints.clear();
    m_rectPoints << m_rect.topLeft()
        << m_rect.topRight()
        << m_rect.bottomRight()
        << m_rect.bottomLeft();
}

void KShape::setAllStyle(QPainter* painter)
{
    QPen pen(m_lineColor);
    pen.setWidthF(m_lineWidth);
    pen.setStyle(m_lineStyle);

    painter->setPen(pen);
    painter->setBrush(m_fillColor);
}

void KShape::addSvgRotation(QDomElement& elem, const QRectF& bound) const
{
    if (rotation() == 0.0)
        return;

    QPointF center = mapToScene(bound.center()); //关键点
    qDebug() << center;
    QString transformStr = QString("rotate(%1 %2 %3)")
        .arg(rotation())
        .arg(center.x())
        .arg(center.y());

    elem.setAttribute("transform", transformStr);
}

QString KShape::penStyleToDashArray(Qt::PenStyle style) const
{
    switch (style)
    {
    case Qt::SolidLine:
        return ""; // SVG 默认就是实线
    case Qt::DashLine:
        return "4,4";
    case Qt::DotLine:
        return "1,4";
    case Qt::DashDotLine:
        return "4,4,1,4";
    case Qt::DashDotDotLine:
        return "4,4,1,4,1,4";
    default:
        return "";
    }
}

Qt::PenStyle KShape::dashArrayToPenStyle(const QString& dash)
{
    if (dash.isEmpty())
        return Qt::SolidLine;

    if (dash == "4,4")
        return Qt::DashLine;
    if (dash == "1,4")
        return Qt::DotLine;
    if (dash == "4,4,1,4")
        return Qt::DashDotLine;
    if (dash == "4,4,1,4,1,4")
        return Qt::DashDotDotLine;

    // 默认 fallback
    return Qt::SolidLine;
}


void KShape::setRotationFromSvg(const QDomElement& elem)
{
    QString transform = elem.attribute("transform");
    if (!transform.startsWith("rotate"))
        return;

    QRegExp rx(R"(rotate\(([-\d\.]+)\s+([-\d\.]+)\s+([-\d\.]+)\))");
    if (rx.indexIn(transform) != -1) {
        qreal angle = rx.cap(1).toDouble();
        qreal cx = rx.cap(2).toDouble();
        qreal cy = rx.cap(3).toDouble();

        setRotation(angle);
        setTransformOriginPoint(mapFromScene(QPointF(cx, cy))); // 反算回 item 本地坐标
    }
}

void KShape::activeInteraction()
{
    finalizeItemGeometry();
    setItemFlags();
}

void KShape::applySvgStyle(const QDomElement& elem)
{
    // 填充色
    QColor fill(elem.attribute("fill", "#ffffff"));
    setFillColor(fill);

    // 边框颜色
    QString strokeAttr = elem.attribute("stroke");
    QColor stroke = strokeAttr.isEmpty() ? QColor(Qt::black) : QColor(strokeAttr);
    setLineColor(stroke);

    // 边框宽度
    qreal strokeWidth = elem.attribute("stroke-width", "1.0").toDouble();
    setLineWidth(strokeWidth);

    // 边框样式
    QString dash = elem.attribute("stroke-dasharray");
    setLineStyle(dash.isEmpty() ? Qt::SolidLine : dashArrayToPenStyle(dash));
}



QRectF KShape::adjustRectForResize(const QRectF& rect, KResizeRegion region, const QPointF& delta)
{
    QRectF result = rect;

    switch (region) {
    case KResizeRegion::TopLeft: {
        QPointF p = rect.topLeft() + delta;
        if (p.x() < rect.right())
            result.setLeft(p.x());
        if (p.y() < rect.bottom())
            result.setTop(p.y());
        break;
    }
    case KResizeRegion::TopRight: {
        QPointF p = rect.topRight() + delta;
        if (p.x() > rect.left())
            result.setRight(p.x());
        if (p.y() < rect.bottom())
            result.setTop(p.y());
        break;
    }
    case KResizeRegion::BottomLeft: {
        QPointF p = rect.bottomLeft() + delta;
        if (p.x() < rect.right())
            result.setLeft(p.x());
        if (p.y() > rect.top())
            result.setBottom(p.y());
        break;
    }
    case KResizeRegion::BottomRight: {
        QPointF p = rect.bottomRight() + delta;
        if (p.x() > rect.left())
            result.setRight(p.x());
        if (p.y() > rect.top())
            result.setBottom(p.y());
        break;
    }
    case KResizeRegion::Top: {
        qreal y = rect.top() + delta.y();
        if (y < rect.bottom())
            result.setTop(y);
        break;
    }
    case KResizeRegion::Bottom: {
        qreal y = rect.bottom() + delta.y();
        if (y > rect.top())
            result.setBottom(y);
        break;
    }
    case KResizeRegion::Left: {
        qreal x = rect.left() + delta.x();
        if (x < rect.right())
            result.setLeft(x);
        break;
    }
    case KResizeRegion::Right: {
        qreal x = rect.right() + delta.x();
        if (x > rect.left())
            result.setRight(x);
        break;
    }
    default:
        break;
    }

    return result; // 如果需要 normalized，返回前需要
}

bool KShape::isResizedRectInBounds(const QRectF& newRect) const
{
    if (!scene())
        return true;

    QRectF sceneBounds = scene()->sceneRect();
    QRectF mappedRect = mapToScene(newRect).boundingRect(); // 转成 scene 坐标

    return sceneBounds.contains(mappedRect);
}